package com.fluidops.keyword.label.provider;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.log4j.Logger;
import org.openrdf.model.URI;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFFormat;
import org.openrdf.rio.RDFParseException;

class MetaReader implements Runnable{

	private static final Logger logger = Logger.getLogger(MetaReader.class.getName());

	private static final int maxTries = 3;

	private RepositoryConnection con;
	private HttpClient client;
	private String dsdURL;
	private URI context;
	private RDFFormat format; 

	MetaReader(RepositoryConnection con, HttpClient client, String dsdURL, URI context, RDFFormat format){
		this.con = con;
		this.client = client;
		this.dsdURL = dsdURL;
		this.context = context;
		this.format = format;
	}

	@Override
	public void run() {
		boolean successful = false;
		for(int numTries = 0; numTries < maxTries && !successful; numTries++){
			HttpMethod method = new GetMethod(this.dsdURL);
			method.setFollowRedirects(true);
			try {
				int status = client.executeMethod(method);
				if (status == HttpStatus.SC_OK) {
					InputStream response = method.getResponseBodyAsStream();
					this.con.add(response, "", this.format, context);
					response.close();
					successful = true;
				}
			} catch (HttpException e) {
				logger.fatal("Fatal protocol violation: " + e.getMessage());
			} catch (IOException e) {
				logger.fatal("IO Error while processing package " + this.dsdURL + ": " + e.getMessage());
			} catch (RDFParseException e) {
				logger.error("RDFParseException while processing package " + this.dsdURL + ": " + e.getMessage());
			} catch (RepositoryException e) {
				logger.fatal("RepositoryException while processing package " + this.dsdURL + ": " + e.getMessage());
			}
			finally {
				method.releaseConnection();
				if(!successful){
					try{
						this.con.rollback();
					} catch(RepositoryException e){
						logger.error("Could not roll back after problem while adding data for " + dsdURL, e);
					}
				}
			}
		}
		try {
			if(this.con.isOpen()){
				this.con.commit();
				this.con.close();
			}
		} catch (RepositoryException e) {
			logger.error("Could not close repository connection of " + dsdURL, e);
		}
	}
}
